package cn.xingzhen.jfield.ui;

import cn.xingzhen.jfield.exception.MessageException;
import cn.xingzhen.jfield.helper.StringHelper;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author yuwan [2020-03-18 01:16]
 * @since
 */
public class MySQLDataField extends DataField {

    static final String MYSQL_URL_UNIX = "jdbc:mysql://%s:%s/%s?useSSL=false";
    static final String MYSQL_URL_WINDOWS = "jdbc:mysql://%s:%s/%s";
    private final String COLUMN_SQL = "select column_name, is_nullable,column_comment," +
            "data_type, character_maximum_length, numeric_precision, numeric_scale " +
            "from information_schema.columns where table_name=? " +
            "and table_schema=? order by ordinal_position asc";

    private Connection connection = null;
    private PreparedStatement ps = null;
    private ResultSet rs = null;

    public MySQLDataField(MainFrame mainFrame) {
        super(mainFrame);
    }

    @Override
    public Connection getConnection() {
        String os = System.getProperty("os.name");
        String url;
        if(os.toLowerCase().startsWith("win")){
            url = String.format(MYSQL_URL_WINDOWS,
                                getFrame().dbHost.getText(),
                                getFrame().dbPort.getText(),
                                getFrame().dbName.getText());
        } else {
            url = String.format(MYSQL_URL_UNIX,
                                getFrame().dbHost.getText(),
                                getFrame().dbPort.getText(),
                                getFrame().dbName.getText());
        }
        try {
            Class.forName("com.mysql.jdbc.Driver");
            //Class.forName("com.mysql.cj.jdbc.Driver");
            Connection connection = DriverManager.getConnection(url, getFrame().dbUser.getText(),
                                                                getFrame().dbPassword.getText());
            return connection;
        } catch (Exception e) {
            e.printStackTrace();
            throw new MessageException("[MYSQL]创建数据库连接异常 {}", e.getMessage());
        }
    }

    @Override
    public Map<String, List<String>> getColumnTypes() {
        Map<String, List<String>> bigMap = new HashMap<>();

        // 可加 @Size 的类型
        List<String> size = new ArrayList<>();
        size.add("varchar");
        //size.add("set");
        //size.add("enum");
        size.add("char");
        size.add("tinytext");
        size.add("text");
        //size.add("mediumtext");
        //size.add("longtext");
        bigMap.put(ToolConfigure.$Size, size);

        // 可加 @Max 的类型
        List<String> max = new ArrayList<>();
        max.add("bigint");
        max.add("integer");
        max.add("int");
        max.add("mediumint");
        max.add("smallint");
        max.add("tinyint");
        bigMap.put(ToolConfigure.$Max, max);

        // 可加 @DecimalMax 的类型
        List<String> decimal = new ArrayList<>();
        decimal.add("float");
        decimal.add("decimal");
        decimal.add("numeric");
        decimal.add("double");
        bigMap.put(ToolConfigure.$Decimal, decimal);

        // 可加 @Date 的类型
        List<String> date = new ArrayList<>();
        date.add("date");
        date.add("year");
        date.add("time");
        date.add("datetime");
        bigMap.put(ToolConfigure.$Date, date);
        return bigMap;
    }

    @Override
    public List<FieldAttr> getColumns() throws SQLException {
        List<FieldAttr> list = new ArrayList<>();
        try {
            connection = getConnection();
            ps = connection.prepareStatement(COLUMN_SQL);
            ps.setString(1, getFrame().tableName.getText());
            ps.setString(2, getFrame().dbName.getText());
            rs = ps.executeQuery();
            String tmp;
            while (rs.next()) {
                FieldAttr column = new FieldAttr();
                column.setName(rs.getString("column_name"));
                column.setComment(rs.getString("column_comment"));
                tmp = rs.getString("is_nullable");
                column.setNullable(tmp.equalsIgnoreCase("yes"));
                column.setType(rs.getString("data_type").toLowerCase());
                tmp = rs.getString("character_maximum_length");
                if (StringHelper.isEmpty(tmp)) {
                    column.setMaxLength(rs.getInt("numeric_precision"));
                } else {
                    column.setMaxLength(Integer.parseInt(tmp));
                }
                column.setPrecision(rs.getInt("numeric_scale"));
                list.add(column);
            }
            if (list.isEmpty()) throw new MessageException("未查询到任何内容，请检查表名是否错误");
        } catch (Exception e) {
            throw e;
        } finally {
            this.close();
        }
        return list;
    }

    @Override
    public void close() {
        try {
            if (rs != null) rs.close();
            if (ps != null) ps.close();
            if (connection != null) connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
